import java.util.*;
import java.sql.*;

public class Armstrong {

	// Constructor
	public Armstrong() {

	}

	// Core method to compute Armstrong Perfect Sample Database
	public boolean compute(ArrayList<String> r, ArrayList<String> r_s,
			ArrayList<ArrayList<String>> maxSets, String table) {

		System.out.println();
		// Database creation and manipulation
		Connection conn = null;
		String url = "jdbc:mysql://localhost/";
		String dbName = "FYP";
		String driver = "com.mysql.jdbc.Driver";
		String userName = "root";
		String password = "";
		try {
			Class.forName(driver);

			// Open connection
			conn = DriverManager
					.getConnection(url + dbName, userName, password);
			System.out.println("Connected to the database");
			Statement st = conn.createStatement();

			// Table creation
			String create = "CREATE TABLE " + table + "(";
			for (int i = 0; i < r.size(); i++) {
				create += r.get(i) + " varchar(256)";
				if (i != r.size() - 1) {
					create += ", ";
				}
			}
			create += ")";
			st.executeUpdate(create);

			// Table manipulation and Armstrong computation logic
			int index = 1;
			SetManipulator setManipulator = new SetManipulator();
			ArrayList<String> nullAdded = new ArrayList<String>();

			for (int i = 0; i < maxSets.size(); i++) {
				String insert1 = "INSERT INTO " + table + " VALUES(";
				String insert2 = "INSERT INTO " + table + " VALUES(";
				ArrayList<String> X = maxSets.get(i);
				ArrayList<String> Z = new ArrayList<String>();

				for (int k = 0; k < maxSets.size(); k++) {
					if (setManipulator.belongs(X, maxSets.get(k))) {
						Z.add(r.get(k));
					}
				}

				ArrayList<String> XZRs = setManipulator.union3(X, Z, r_s);
				ArrayList<String> Rs_X = setManipulator.subtract(r_s, X);
				ArrayList<String> ZRs_X = setManipulator.union2(Z, Rs_X);

				// Checking duplicates
				int dup = 0;

				// Going row by pair of rows
				for (int j = 0; j < r.size(); j++) {

					// First row in pair
					if (XZRs.contains(r.get(j))) {
						if (j < r.size() - 1) {
							insert1 += "'" + r.get(j) + "_" + index + "', ";
						} else {
							insert1 += "'" + r.get(j) + "_" + index + "')";
						}
					} else {
						if (j < r.size() - 1) {
							insert1 += "null, ";
						} else {
							insert1 += "null)";
						}

						if (!nullAdded.contains(r.get(j))) {
							nullAdded.add(r.get(j));
						}
					}

					// Second row in pair
					if (X.contains(r.get(j))) {
						if (j < r.size() - 1) {
							insert2 += "'" + r.get(j) + "_" + index + "', ";
						} else {
							insert2 += "'" + r.get(j) + "_" + index + "')";
						}
					} else {
						if (ZRs_X.contains(r.get(j))) {
							if (j < r.size() - 1) {
								insert2 += "'" + r.get(j) + "_" + (index + 1)
										+ "', ";
							} else {
								insert2 += "'" + r.get(j) + "_" + (index + 1)
										+ "')";
							}
							dup++;
						} else {
							if (j < r.size() - 1) {
								insert2 += "null, ";
							} else {
								insert2 += "null)";
							}

							if (!nullAdded.contains(r.get(j))) {
								nullAdded.add(r.get(j));
							}
						}
					}
				}

				if (dup == r.size()) {
					st.executeUpdate(insert1);
					index += 1;
				} else {
					st.executeUpdate(insert1);
					st.executeUpdate(insert2);
					index += 2;
				}
			}

			// Making sure there is NULL items
			ArrayList<String> nullables = new ArrayList<String>();
			nullables = setManipulator.subtract(r, r_s);
			ArrayList<String> leftover = new ArrayList<String>();
			leftover = setManipulator.subtract(nullables, nullAdded);

			if (leftover.size() > 0) {
				String insert = "INSERT INTO " + table + " VALUES(";
				for (int i = 0; i < r.size(); i++) {
					if (leftover.contains(r.get(i))) {
						if (i < r.size() - 1) {
							insert += "null, ";
						} else {
							insert += "null)";
						}
					} else {
						if (i < r.size() - 1) {
							insert += "'" + r.get(i) + "_" + index + "', ";
						} else {
							insert += "'" + r.get(i) + "_" + index + "')";
						}
					}
				}
				st.executeUpdate(insert);
			}

			// Close connection
			conn.close();
			System.out.println("Disconnected from database");
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
}
